#include "disp.h" /* include your own disp.h file (e.g. hw1)*/
#include "common.h"
#include <vector>

using namespace std;

/* Camera defaults */
#define	DEFAULT_FOV		35.0
#define	DEFAULT_IM_Z	(-10.0)  /* world coords for image plane origin */
#define	DEFAULT_IM_Y	(5.0)    /* default look-at point = 0,0,0 */
#define	DEFAULT_IM_X	(-10.0)

#define	DEFAULT_AMBIENT	{0.1, 0.1, 0.1}
#define	DEFAULT_DIFFUSE	{0.7, 0.6, 0.5}
#define	DEFAULT_SPECULAR	{0.2, 0.3, 0.4}
#define	DEFAULT_SPEC		32

#define	MATLEVELS	100		/* how many matrix pushes allowed */
#define	MAX_LIGHTS	10		/* how many lights allowed */

/* Dummy definition : change it later */
#ifndef GzLight
//#define GzLight		GzPointer
#endif

#ifndef GzTexture
//#define GzTexture	GzPointer
#endif

#ifndef GZRENDER
#define GZRENDER
typedef struct {			/* define a renderer */
  GzRenderClass	renderClass;
  GzDisplay		*display;
  short		    open;
  GzCamera		camera;
  short		    matlevel;	        /* top of stack - current xform */
  GzMatrix		Ximage[MATLEVELS];	/* stack of xforms (Xsm) */
  GzMatrix		Xnorm[MATLEVELS];	/* xforms for norms (Xim) */
  GzMatrix		Xraytrace[MATLEVELS]; /* transform vertex from model space to image space */

  GzMatrix		Xsp;		        /* NDC to screen (pers-to-screen) */
  GzColor		flatcolor;          /* color state for flat shaded triangles */
  int			interp_mode;
  int			numlights;
  GzLight		lights[MAX_LIGHTS];
  GzLight		ambientlight;
  GzColor		Ka, Kd, Ks;
  float		    spec;		/* specular power */
  GzTexture		tex_fun;    /* tex_fun(float u, float v, GzColor color) */

  vector<Triangle>* triangleBuffer;
  int			numTriangle;

}  GzRender;

typedef struct{

  int			numlights;
  int			numTriangle;
  GzLight		lights[MAX_LIGHTS];
  GzLight		ambientlight;
  GzColor		Ka, Kd, Ks;
  float		    spec;		/* specular power */

} GzRenderCUDA;

typedef struct{
	//flat shading
	GzCoord start;
	GzCoord end;
	GzCoord current;
	float slopeX;
	float slopeZ;

	//Gouraud shading
	GzColor startColor;
	GzColor endColor;
	GzColor currentColor;
	float slopeR;
	float slopeG;
	float slopeB;

	//Phong shading
	GzCoord startNormal;
	GzCoord endNormal;
	GzCoord currentNormal;
	float slopeNX;
	float slopeNY;
	float slopeNZ;

	//texturing
	GzCoord startUV;
	GzCoord endUV;
	GzCoord currentUV;
	float slopeU;
	float slopeV;

} GzDDA;

#define PIII 3.1415926
#define DIM 16

#endif

// Function declaration
// HW2
int GzNewRender(GzRender **render, GzRenderClass renderClass, GzDisplay *display);
int GzFreeRender(GzRender *render);
int GzBeginRender(GzRender	*render);
int GzPutAttribute(GzRender	*render, int numAttributes, GzToken	*nameList, 
	GzPointer *valueList);
int GzPutTriangle(GzRender *render, int	numParts, GzToken *nameList,
	GzPointer *valueList);

// CUDA Project
int GzSaveTriangle(GzRender *render, int numParts, GzToken *nameList, GzPointer *valueList);
int GzRayTraceRender(GzRender *render);
int GzRayTraceCUDA(GzRender *render);

// HW3
int GzPutCamera(GzRender *render, GzCamera *camera);
int GzPushMatrix(GzRender *render, GzMatrix	matrix);
int GzPopMatrix(GzRender *render);

// Object Translation
int GzRotXMat(float degree, GzMatrix mat);
int GzRotYMat(float degree, GzMatrix mat);
int GzRotZMat(float degree, GzMatrix mat);
int GzTrxMat(GzCoord translate, GzMatrix mat);
int GzScaleMat(GzCoord scale, GzMatrix mat);


